{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "4878c858",
   "metadata": {},
   "source": [
    "## 构建搜索API\n",
    "### 具体运行service.py，具体操作：\n",
    "\n",
    "- 终端运行\n",
    "~~~\n",
    "python service.py\n",
    "~~~\n",
    "\n",
    "- 网页搜索：http://172.20.50.49:8000/api/search?q=要搜索的内容\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d09eaa35",
   "metadata": {},
   "source": [
    "## 以下仅供参考\n",
    "### 创建NeuralSearcher类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "649ae85e",
   "metadata": {},
   "outputs": [],
   "source": [
    "from qdrant_client import QdrantClient\n",
    "from sentence_transformers import SentenceTransformer\n",
    "\n",
    "\n",
    "class NeuralSearcher:\n",
    "    def __init__(self, collection_name):\n",
    "        self.collection_name = collection_name\n",
    "        # Initialize encoder model\n",
    "        self.model = SentenceTransformer(\"./model/all-MiniLM-L6-v2\", device=\"cuda\")\n",
    "        # initialize Qdrant client\n",
    "        self.qdrant_client = QdrantClient(\"http://localhost:6333\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ecda6800",
   "metadata": {},
   "source": [
    "### 搜索函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bd4cf2d8",
   "metadata": {},
   "outputs": [],
   "source": [
    "def search(self, text: str):\n",
    "    # Convert text query into vector\n",
    "    vector = self.model.encode(text).tolist()\n",
    "\n",
    "    # Use `vector` for search for closest vectors in the collection\n",
    "    search_result = self.qdrant_client.query_points(\n",
    "        collection_name=self.collection_name,\n",
    "        query=vector,\n",
    "        query_filter=None,  # If you don't want any filters for now\n",
    "        limit=5,  # 5 the most closest results is enough\n",
    "    ).points\n",
    "    # `search_result` contains found vector ids with similarity scores along with the stored payload\n",
    "    # In this function you are interested in payload only\n",
    "    payloads = [hit.payload for hit in search_result]\n",
    "    return payloads"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ea18b71e",
   "metadata": {},
   "source": [
    "### 下述三行仅限jupyter使用，py文件中只需要第一行"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "468416e6",
   "metadata": {},
   "outputs": [],
   "source": [
    "from fastapi import FastAPI\n",
    "import nest_asyncio\n",
    "nest_asyncio.apply()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d955906d",
   "metadata": {},
   "source": [
    "### 服务"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8fe1ac46",
   "metadata": {},
   "outputs": [],
   "source": [
    "app = FastAPI()\n",
    "\n",
    "# Create a neural searcher instance\n",
    "neural_searcher = NeuralSearcher(collection_name=\"startups\")\n",
    "\n",
    "\n",
    "@app.get(\"/api/search\")\n",
    "def search_startup(q: str):\n",
    "    return {\"result\": neural_searcher.search(text=q)}\n",
    "\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    import uvicorn\n",
    "\n",
    "    uvicorn.run(app, host=\"0.0.0.0\", port=8000)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
